package com.crazy.controller.sys;

import static com.crazy.common.page.Pager.DEFAULT_COUNT;
import static com.crazy.security.ValidateCodeBean.VALIDCODE;
import static org.hibernate.criterion.Order.asc;
import static org.hibernate.criterion.Order.desc;
import static org.springframework.util.StringUtils.hasText;
import static org.springframework.validation.ValidationUtils.rejectIfEmptyOrWhitespace;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.data.domain.Page;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.crazy.common.constants.Const;
import com.crazy.entity.sys.PubRole;
import com.crazy.entity.sys.PubUser;
import com.crazy.service.sys.PubResourceService;
import com.crazy.service.sys.PubRoleService;
import com.crazy.service.sys.PubUserService;

/**
 * 用户控制器
 * 
 * @author Zhang Weiwei
 * @since 2013-9-19下午2:46:10
 */
@Controller
@RequestMapping("/sys")
public class PubUserController {
	private static String VIEWNAME = "sys/user/";
	private static final String LISTURL = "sys/user/list";
	private static final String SUCCESS = "redirect:/success.jsp";
	@Inject
	private PasswordEncoder encoder;
	@Inject
	private PubUserService userService;
	@Inject
	private PubRoleService roleService;
	@Inject
	private PubResourceService resService;

	/**
	 * 显示用户列表
	 * 
	 * @since 2013-9-25下午8:45:27
	 */
	@RequestMapping("/user/list")
	public String list(Integer pageNo, Model model) {
		Page<PubUser> pager = this.userService.findAll(pageNo, DEFAULT_COUNT,
				desc("createTime"));
		model.addAttribute("pager", pager);
		return VIEWNAME.concat("list");
	}

	/**
	 * 跳转到添加用户页面
	 * 
	 * @since 2013-9-25下午8:45:31
	 */
	@RequestMapping("/user/add")
	public String toAdd(Model model) {
		List<PubRole> list = this.roleService.findByProperty("enabled",
				Const.ENABLE.getStatus(), asc("createTime"));
		model.addAttribute("list", list);
		model.addAttribute("user", new PubUser());
		return VIEWNAME.concat("add");
	}

	/**
	 * 添加用户
	 * 
	 * @since 2013-9-25下午8:45:35
	 */
	@RequestMapping("/user/doAdd")
	public String doAdd(@ModelAttribute("user") PubUser user, Errors errors,
			@AuthenticationPrincipal PubUser login, Model model) {
		if (this.validate(errors, true)) {
			user.setPubRoles(user.getPubRoles());
			List<PubRole> list = this.roleService.findByProperty("enabled",
					Const.ENABLE.getStatus(), asc("createTime"));
			model.addAttribute("list", list);
			model.addAttribute("user", user);
			return VIEWNAME.concat("add");
		}
		if (login != null) {
			user.setCreator(login.getUserAccount());
		}
		user.setCreateTime(new Date());
		String password = this.encoder.encode(user.getUserPassword());
		user.setUserPassword(password);
		this.userService.save(user);
		model.addAttribute("url", LISTURL);
		return SUCCESS;
	}

	/**
	 * 跳转到修改用户页面
	 * 
	 * @since 2013-9-25下午8:45:41
	 */
	@RequestMapping("/user/update/{id}")
	public String toUpdate(@PathVariable String id, Model model) {
		PubUser user = this.userService.get(id);
		List<PubRole> list = this.roleService.findByProperty("enabled",
				Const.ENABLE.getStatus(), asc("createTime"));
		model.addAttribute("list", list);
		model.addAttribute("user", user);
		return VIEWNAME.concat("update");
	}

	/**
	 * 修改用户
	 * 
	 * @since 2013-9-25下午8:45:49
	 */
	@RequestMapping("/user/doUpdate")
	public String doUpdate(@ModelAttribute("user") PubUser user, Errors errors,
			Model model) {
		if (this.validate(errors, false)) {
			List<PubRole> list = this.roleService.findByProperty("enabled",
					Const.ENABLE.getStatus(), asc("createTime"));
			model.addAttribute("list", list);
			model.addAttribute("user", user);
			return VIEWNAME.concat("update");
		}
		PubUser entity = this.userService.get(user.getUserId());
		entity.setPubRoles(user.getPubRoles());
		if (hasText(user.getUserPassword())) {
			String password = this.encoder.encode(user.getUserPassword());
			entity.setUserPassword(password);
		}
		entity.setEnabled(user.isEnabled());
		entity.setUserAccount(user.getUserAccount());
		entity.setUserDesc(user.getUserDesc());
		entity.setUserName(user.getUserName());
		this.userService.update(entity);
		model.addAttribute("url", LISTURL);
		return SUCCESS;
	}

	/**
	 * 删除用户
	 * 
	 * @since 2013-9-25下午8:45:59
	 */
	@RequestMapping("/user/delete/{id}")
	public String delete(@PathVariable String id, Model model) {
		this.userService.deleteByPK(id);
		model.addAttribute("url", LISTURL);
		return SUCCESS;
	}

	/**
	 * @return 用户设置
	 */
	@RequestMapping("/user/setting")
	public String setting() {
		return VIEWNAME.concat("setting");
	}

	/**
	 * @return 用户设置
	 */
	@RequestMapping("/user/doSetting")
	public String doSetting(@ModelAttribute("user") PubUser user,
			@AuthenticationPrincipal PubUser login, Model model) {
		String password = this.encoder.encode(user.getUserPassword());
		login.setUserPassword(password);
		login.setUserAccount(user.getUserAccount());
		this.userService.update(login);
		return "redirect:/j_spring_security_logout";
	}

	/**
	 * 后台用户登录成功之后，移除验证码，查询菜单列表，将其放入session作用域中
	 * 
	 * @since 2013-11-3下午6:28:07
	 */
	@RequestMapping("/admin")
	public String main(HttpServletRequest request,
			@AuthenticationPrincipal PubUser user) {
		if (user != null) {
			HttpSession session = request.getSession();
			session.removeAttribute(VALIDCODE);
			if (session.getAttribute("menuList") == null) {
				String menuList = this.resService.findMenuListToJsonString(
						user.getUserId(), request.getContextPath());
				session.setAttribute("menuList", menuList);
			}
		}
		return "sys/main";
	}

	@RequestMapping("/left")
	public String left() {
		return "sys/left";
	}

	@RequestMapping("/right")
	public String right() {
		return "sys/right";
	}

	/**
	 * 验证用户对象
	 * 
	 * @since 2013-11-10下午8:30:56
	 */
	private boolean validate(Errors errors, boolean flag) {
		rejectIfEmptyOrWhitespace(errors, "userAccount", "userAccount.isNull");
		rejectIfEmptyOrWhitespace(errors, "pubRoles", "pubRoles.isNull");
		if (flag) {
			rejectIfEmptyOrWhitespace(errors, "userPassword",
					"userPassword.isNull");
		}
		return errors.hasErrors();
	}
}
